package com.zkh.myutils.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正则表达式工具
 * @author zkh
 * @since 1.5
 */
public final class Regexp {
	//要操作的字符串
	private String target;
	
	/**
	 * 构造器
	 * @param target 要操作的字符串
	 */
	public Regexp(String target){
		if(target==null){
			this.target = "";
		}else{
			this.target = target;
		}
	}
	
	/**
	 * 字符串中是否存在匹配模式
	 * @param regex 正则表达式
	 * @return 匹配到返回true，否则返回false
	 */
	public boolean isExist(String regex){
		return isExist(regex, target, false);
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @return 如果字符串是以指定正则模式开始，就返回true，否则返回false
	 */
	public boolean isStartWith(String regex){
		return isStartWith(regex, target, false);
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @return 如果字符串是以指定正则模式结尾，就返回true，否则返回false
	 */
	public boolean isEndWith(String regex){
		return isEndWith(regex, target, false);
	}
	
	/**
	 * 字符串是否和正则表达式完全匹配
	 * @param regex 正则表达式
	 * @return 如果字符串和正则表达式完全匹配，则返回true，否则返回false
	 */
	public boolean isMatch(String regex){
		return isMatch(regex, target, false);
	}
	
	/**
	 * 获取匹配到的第一个子字符串
	 * @param regex 正则表达式
	 * @return 如果未匹配到，返回null，否则返回第一个子字符串
	 */
	public String getMatchOne(String regex){
		return getMatchOne(regex, target, false);
	}
	
	/**
	 * 获取匹配到的所有子字符串
	 * @param regex 正则表达式
	 */
	public List<String> getMatchesAll(String regex){
		return getMatchesAll(regex, target, false);
	}
	
	/**
	 * 获取所有匹配项，并保存在自定义ResultSet对象中
	 * @param regex 正则表达式
	 */
	public List<ResultSet> getResultSet(String regex){
		return getResultSet(regex, target, false);
	}
	
	/****************为上述方式区分大小写****************/
	/**
	 * 字符串中是否存在匹配模式
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 * @return 匹配到返回true，否则返回false
	 */
	public boolean isExist(String regex, boolean ignoreCase){
		return isExist(regex, target, ignoreCase);
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 * @return 如果字符串是以指定正则模式开始，就返回true，否则返回false
	 */
	public boolean isStartWith(String regex,boolean ignoreCase){
		return isStartWith(regex, target, ignoreCase);
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 * @return 如果字符串是以指定正则模式结尾，就返回true，否则返回false
	 */
	public boolean isEndWith(String regex, boolean ignoreCase){
		return isEndWith(regex, target, ignoreCase);
	}
	
	/**
	 * 字符串是否和正则表达式完全匹配
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 * @return 如果字符串和正则表达式完全匹配，则返回true，否则返回false
	 */
	public boolean isMatch(String regex, boolean ignoreCase){
		return isMatch(regex, target, ignoreCase);
	}
	
	/**
	 * 获取匹配到的第一个子字符串
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 * @return 如果未匹配到，返回null，否则返回第一个子字符串
	 */
	public String getMatchOne(String regex, boolean ignoreCase){
		return getMatchOne(regex, target, ignoreCase);
	}
	
	/**
	 * 获取匹配到的所有子字符串
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 */
	public List<String> getMatchesAll(String regex, boolean ignoreCase){
		return getMatchesAll(regex, target, ignoreCase);
	}
	
	/**
	 * 获取所有匹配项，并保存在自定义ResultSet对象中
	 * @param regex 正则表达式
	 * @param ignoreCase 是否区分大小写
	 */
	public List<ResultSet> getResultSet(String regex, boolean ignoreCase){
		return getResultSet(regex, target, ignoreCase);
	}
	
	
	/****************为上述方法提供静态方法****************/
	
	/**
	 * 字符串中是否存在匹配模式
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @return 匹配到返回true，否则返回false
	 */
	public static boolean isExist(String regex, String target){
		return isExist(regex, target, false);
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @return 如果字符串是以指定正则模式开始，就返回true，否则返回false
	 */
	public static boolean isStartWith(String regex, String target){
		return isStartWith(regex, target, false);
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @return 如果字符串是以指定正则模式结尾，就返回true，否则返回false
	 */
	public static boolean isEndWith(String regex, String target){
		return isEndWith(regex, target, false);
	}
	
	/**
	 * 字符串是否和正则表达式完全匹配
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @return 如果字符串和正则表达式完全匹配，则返回true，否则返回false
	 */
	public static boolean isMatch(String regex, String target){
		return isMatch(regex, target, false);
	}
	
	/**
	 * 获取匹配到的第一个子字符串
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @return 如果未匹配到，返回null，否则返回第一个子字符串
	 */
	public static String getMatchOne(String regex, String target){
		return getMatchOne(regex, target, false);
	}
	
	/**
	 * 获取匹配到的所有子字符串
	 * @param regex 正则表达式
	 * @param target 目标字符
	 */
	public static List<String> getMatchesAll(String regex,String target){
		return getMatchesAll(regex, target, false);
	}
	
	/**
	 * 获取所有匹配项，并保存在自定义ResultSet对象中
	 * @param regex 正则表达式
	 * @param target 目标字符
	 */
	public static List<ResultSet> getResultSet(String regex,String target){
		return getResultSet(regex, target, false);
	}
	
	/**********为上述方式提供忽略大小写的重写方法****************/
	
	/**
	 * 字符串中是否存在匹配模式
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 * @return 匹配到返回true，否则返回false
	 */
	public static boolean isExist(String regex, String target, boolean ignoreCase){
		//如果传入的字符串为空，则返回false
		if(target==null){
			return false;
		}
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		//返回结果
		return matcher.find();
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 * @return 如果字符串是以指定正则模式开始，就返回true，否则返回false
	 */
	public static boolean isStartWith(String regex, String target, boolean ignoreCase){
		//如果传入的字符串为空，则返回false
		if(target==null){
			return false;
		}
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		//返回结果，是否以regex模式开头
		return matcher.lookingAt();
	}
	
	/**
	 * 是否以指定正则模式开始
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 * @return 如果字符串是以指定正则模式结尾，就返回true，否则返回false
	 */
	public static boolean isEndWith(String regex, String target, boolean ignoreCase){
		//首先检测是否字符串中是否存在指定正则模式
		if(!isExist(regex, target, ignoreCase)){
			return false;
		}
		//如果字符串匹配到了正则模式，则继续查找
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		//字符串最后一个字符的偏移量
		int end = target.length();
		//循环遍历matcher
		while(matcher.find()){
			if(matcher.end()==end){
				return true;
			}
		}
		//如果不满足条件，则字符串不是以指定正则结尾
		return false;
	}
	
	/**
	 * 字符串是否和正则表达式完全匹配
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 * @return 如果字符串和正则表达式完全匹配，则返回true，否则返回false
	 */
	public static boolean isMatch(String regex, String target, boolean ignoreCase){
		//如果传入的字符串为空，则返回false
		if(target==null){
			return false;
		}
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		//返回结果，是否与regex完全匹配
		return matcher.matches();
	}
	
	/**
	 * 获取匹配到的第一个子字符串
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 * @return 如果未匹配到，返回null，否则返回第一个子字符串
	 */
	public static String getMatchOne(String regex, String target, boolean ignoreCase){
		//如果传入的字符串为空，则返回false
		if(target==null){
			return null;
		}
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		//返回结果
		if(matcher.find()){
			return matcher.group();
		}else{
			return null;
		}
	}
	
	/**
	 * 获取匹配到的所有子字符串
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 */
	public static List<String> getMatchesAll(String regex,String target, boolean ignoreCase){
		//定义List集合
		List<String> results = new ArrayList<>();
		//如果传入的字符串为空，则返回false
		if(target==null){
			return results;
		}
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		while(matcher.find()){
			results.add(matcher.group());
		}
		//返回结果
		return results;
	}
	
	/**
	 * 获取所有匹配项，并保存在自定义ResultSet对象中
	 * @param regex 正则表达式
	 * @param target 目标字符
	 * @param ignoreCase 是否忽略大小写，true为是，false为不是
	 */
	public static List<ResultSet> getResultSet(String regex,String target,boolean ignoreCase){
		//定义List集合
		List<ResultSet> rss = new ArrayList<>();
		//如果传入的字符串为空，则返回false
		if(target==null){
			return rss;
		}
		//构建正则模式
		Pattern p = null;
		if(ignoreCase){
			p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
		}else{
			p = Pattern.compile(regex);
		}
		//获取Matcher
		Matcher matcher = p.matcher(target);
		
		while(matcher.find()){
			//创建结果集对象
			ResultSet rs = new ResultSet();
			//给结果集成员变量赋值
			rs.setResult(matcher.group());
			rs.setStart(matcher.start());
			rs.setEnd(matcher.end());
			//将结果集对象添加到集合中
			rss.add(rs);
		}
		//返回结果
		return rss;
	}
	
	/**
	 * 匹配结果集
	 * @author zkh
	 */
	public static final class ResultSet{
		//匹配结果
		private String result;
		//匹配结果开始索引
		private int start;
		//匹配结果结束索引+1
		private int end;
		
		//getter和setter
		public String getResult() {
			return result;
		}
		public void setResult(String result) {
			this.result = result;
		}
		public int getStart() {
			return start;
		}
		public void setStart(int start) {
			this.start = start;
		}
		public int getEnd() {
			return end;
		}
		public void setEnd(int end) {
			this.end = end;
		}
		@Override
		public String toString() {
			return "ResultSet [result=" + result + ", start=" + start
					+ ", end=" + end + "]";
		}
		
	}
}
